/**
 * file: SimpleJobProcessingworker.java
 */

package pcsd.worker;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import pcsd.worker.JobProcessingWorker;

import pcsd.Result;
import pcsd.Task;

/**
 * A simple job processing worker implementation.
 * 
 * @author Tim van Deurzen
 */
public class SimpleJobProcessingWorker implements JobProcessingWorker {
	
	private String workerName = "";

	public static int workerNum = 0;
	
	/**
	 * Constructor to start with an empty job queue.
	 */
	public SimpleJobProcessingWorker(int workerNum) throws RemoteException {
		this.workerName = "worker-" + workerNum;
	}

	/** see interface. */
	@Override
	public Result executeTask(Task task) throws RemoteException {
		return task.execute();
	}
	
	/**
	 * Get the identifying name for this worker.
	 * 
	 * @return
	 */
	public String getWorkerName() {
		return this.workerName;
	}

	/**
	 * Main method.
	 * 
	 * Instantiate a worker object and start processing tasks.
	 */
	public static void main(String[] args) {
	    if (System.getSecurityManager() == null) {
			System.setSecurityManager(new SecurityManager());
		}
	    
		try {
		    parseArgs(args);

			JobProcessingWorker worker = new SimpleJobProcessingWorker(workerNum);
			
			JobProcessingWorker stub =
					(JobProcessingWorker) UnicastRemoteObject.exportObject(worker, 0);
			
			/*
			 * If you want more control over where the registry is running, you
			 * might consider passing the hostname and port as commandline
			 * arguments.
			 */
			Registry registry = LocateRegistry.getRegistry();
			
			registry.rebind("worker-" + workerNum, stub);
			
			System.out.println("Worker " + workerNum + " bound");
		} catch (Exception e) {
			System.err.println("SimpleJobProcessingWorker exception:");
			e.printStackTrace();
		}
	}

	public static void usage() {
	    System.out.println("Usage: java SimpleJobQueueServer <worker_id>");
	    System.out.println( "\t The worker id should be an integer that "
	                      + "identifies the worker.");
	    System.out.println("\n");
    }

    /**
     * Parse commandline arguments.
     *
     * Instead of mixing this code into the code in main, we use this function
     * to allow easy extension of the number of arguments.
     */
    public static void parseArgs(String[] args) {
        int argc = args.length,
            i    = 0;

        if (argc == 0) {
            usage();
        }

        for (; i < argc; i++) {
            try {
                workerNum = Integer.parseInt(args[i]);
            } catch(NumberFormatException e) {
                System.out.println("Number of workers must be a valid integer!");
                usage();
            }
        }
    }
}
